#region Copyright (c) 2006-2010 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2010 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Widgetsphere.Generator.Models;
using Widgetsphere.Generator.Common.Util;
using System.Collections;
using System.Collections.ObjectModel;
using Widgetsphere.Generator.ProjectItemGenerators;

namespace Widgetsphere.Generator.DALProxy.ProjectItemGenerators.DataTransferViewExtensionObject
{
	class DTOExtensionViewGeneratedTemplate : BaseDALProxyTemplate
	{
		private StringBuilder sb = new StringBuilder();
		private CustomView _currentView;

		public DTOExtensionViewGeneratedTemplate(ModelRoot model, CustomView view)
		{
			_model = model;
			_currentView = view;
		}

		#region BaseClassTemplate overrides
		public override string FileName
		{
			get { return string.Format("{0}.Generated.cs", _currentView.PascalName); }
		}

		public string ParentItemName
		{
			get { return string.Format("{0}.cs", _currentView.PascalName); }
		}

		public override string FileContent
		{
			get
			{
				GenerateContent();
				return sb.ToString();
			}
		}

		#endregion

		#region GenerateContent

		private void GenerateContent()
		{
			try
			{
				ValidationHelper.AppendCopyrightInCode(sb, _model);
				this.AppendUsingStatements();
				sb.AppendLine("namespace " + DefaultNamespace + ".Extensions");
				sb.AppendLine("{");
				this.AppendClass();
				sb.AppendLine("}");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

		#region namespace / objects

		public void AppendUsingStatements()
		{
			sb.AppendLine("using System;");
			sb.AppendLine("using System.Collections.Generic;");
			sb.AppendLine("using System.Linq;");
			sb.AppendLine("using System.Text;");
			sb.AppendLine("using System.Xml;");
			sb.AppendLine("using System.ComponentModel;");
			sb.AppendLine("using System.Data;");
			sb.AppendLine("using " + _model.CompanyName + "." + _model.ProjectName + ".DataTransfer;");
			sb.AppendLine("using " + _model.CompanyName + "." + _model.ProjectName + ".Business.Objects;");
			sb.AppendLine("using Widgetsphere.Core.DataAccess;");
			sb.AppendLine("using System.Linq.Expressions;");
			sb.AppendLine("using " + _model.CompanyName + "." + _model.ProjectName + ".Business.LINQ;");
			sb.AppendLine("using Widgetsphere.Core.Util;");
			sb.AppendLine("using " + _model.CompanyName + "." + _model.ProjectName + ".Business.Views;");
			sb.AppendLine();
		}

		private void AppendClass()
		{
			try
			{
				sb.AppendLine("	/// <summary>");
				sb.AppendLine("	/// This is a set of extensions for the " + _currentView.PascalName + " DAL/DTO object");
				sb.AppendLine("	/// </summary>");
				sb.AppendLine("	public static partial class " + _currentView.PascalName + "Extension");
				sb.AppendLine("	{");

				#region Fill DAL
				sb.AppendLine("		#region Fill DAL");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Populate a DAL object from its corresponding DTO.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		/// <param name=\"item\">The empty DAL object.</param>");
				sb.AppendLine("		/// <param name=\"dtoItem\">The source DTO to load.</param>");
				sb.AppendLine("		public static void Fill(this " + _currentView.PascalName + " item, " + _currentView.PascalName + "DTO dtoItem)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (dtoItem == null) throw new Exception(\"The " + _currentView.PascalName + " DTO cannot be null.\");");
				sb.AppendLine("			if (item == null) throw new Exception(\"The " + _currentView.PascalName + " item cannot be null.\");");
				sb.AppendLine("			DataRow dr = ((DataRow)((IWrappingClass)item).WrappedClass);");
				foreach (CustomViewColumn column in _currentView.GetColumns().Where(x => x.Generated))
				{
					if (column.AllowNull)
					{
						sb.AppendLine("			if (dtoItem." + column.PascalName + " == null) dr[\"" + column.DatabaseName + "\"] = System.DBNull.Value;");
						sb.AppendLine("			else dr[\"" + column.DatabaseName + "\"] = dtoItem." + column.PascalName + ";");
					}
					else
					{
						sb.AppendLine("			dr[\"" + column.DatabaseName + "\"] = dtoItem." + column.PascalName + ";");
					}
				}

				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		#endregion");
				sb.AppendLine();
				#endregion

				#region Fill DTO

				sb.AppendLine("		#region Fill DTO");
				sb.AppendLine();
				//Fill for DTO collection
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Populate a DTO object collection from its corresponding DAL object collection.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		/// <param name=\"list\">The destination DTO collection.</param>");
				sb.AppendLine("		/// <param name=\"" + _currentView.CamelName + "Collection\">The source DAL collection.</param>");
				sb.AppendLine("		public static void Fill(this List<" + _currentView.PascalName + "DTO> list, " + _currentView.PascalName + "Collection " + _currentView.CamelName + "Collection)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (" + _currentView.CamelName + "Collection == null) throw new Exception(\"The " + _currentView.PascalName + " collection cannot be null.\");");
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			foreach (" + _currentView.PascalName + " item in " + _currentView.CamelName + "Collection)");
				sb.AppendLine("			{");
				sb.AppendLine("				" + _currentView.PascalName + "DTO newItem = new " + _currentView.PascalName + "DTO();");
				sb.AppendLine("				newItem.Fill(item);");
				sb.AppendLine("				list.Add(newItem);");
				sb.AppendLine("			}");
				sb.AppendLine("		}");
				sb.AppendLine();

				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Populate a DTO object from its corresponding DAL object.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		/// <param name=\"item\">The source DAL object.</param>");
				sb.AppendLine("		/// <param name=\"dtoItem\">The empty DTO to load.</param>");
				sb.AppendLine("		public static void Fill(this " + _currentView.PascalName + "DTO dtoItem, " + _currentView.PascalName + " item)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (dtoItem == null) throw new Exception(\"The " + _currentView.PascalName + " DTO cannot be null.\");");
				sb.AppendLine("			if (item == null) throw new Exception(\"The " + _currentView.PascalName + " item cannot be null.\");");

				foreach (CustomViewColumn column in _currentView.GetColumns().Where(x => x.Generated).OrderBy(x => x.DatabaseName))
				{
					//Normal property
					sb.AppendLine("			dtoItem." + column.PascalName + " = item." + column.PascalName + ";");
				}

				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		#endregion");
				sb.AppendLine();
				#endregion

				#region RunSelect
				sb.AppendLine("		#region RunSelect");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Select all objects from store.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public static void RunSelect(this List<" + _currentView.PascalName + "DTO> list)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			" + _currentView.PascalName + "Collection retval = " + _currentView.PascalName + "Collection.RunSelect();");
				sb.AppendLine("			foreach (" + _currentView.PascalName + " item in retval)");
				sb.AppendLine("			{");
				sb.AppendLine("				" + _currentView.PascalName + "DTO newItem = new " + _currentView.PascalName + "DTO();");
				sb.AppendLine("				newItem.Fill(item);");
				sb.AppendLine("				list.Add(newItem);");
				sb.AppendLine("			}");
				sb.AppendLine("		}");
				sb.AppendLine();

				//RunSelect LINQ
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a result set.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public static void RunSelect(this List<" + _currentView.PascalName + "DTO> list, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			list.Fill(" + _currentView.PascalName + "Collection.RunSelect(where));");
				sb.AppendLine("		}");
				sb.AppendLine();

				sb.AppendLine("		#endregion");
				sb.AppendLine();
				#endregion

				#region RunSelect Paged

				sb.AppendLine("		#region RunSelect Paged");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a paged result set.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public static PagedQueryResults<" + _currentView.PascalName + "DTO> RunSelect(this List<" + _currentView.PascalName + "DTO> list, string pageSize, string page, string sortOrder, string sortColumn, string linq)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			#region Setup Variables and Error Check");
				sb.AppendLine("			int po;");
				sb.AppendLine("			int rpp;");
				sb.AppendLine();
				sb.AppendLine("			if (!int.TryParse(page, out po)) throw new Exception(\"The page number number is not a valid integer!\");");
				sb.AppendLine("			if (po < 1) po = 1;");
				sb.AppendLine();
				sb.AppendLine("			if (!int.TryParse(pageSize, out rpp)) throw new Exception(\"The page size is not a valid integer!\");");
				sb.AppendLine("			if (rpp < 1) rpp = 1;");
				sb.AppendLine();
				sb.AppendLine("			" + _currentView.PascalName + ".FieldNameConstants sortField;");
				sb.AppendLine("			try");
				sb.AppendLine("			{");
				sb.AppendLine("				sortField = (" + _currentView.PascalName + ".FieldNameConstants)Enum.Parse(typeof(" + _currentView.PascalName + ".FieldNameConstants), sortColumn);");
				sb.AppendLine("			}");
				sb.AppendLine("			catch");
				sb.AppendLine("			{");
				sb.AppendLine("				throw new Exception(\"The sort field is not valid!\");");
				sb.AppendLine("			}");
				sb.AppendLine();
				sb.AppendLine("			bool ascending = (sortOrder.ToLower() == \"asc\" || sortOrder.ToLower() == \"ascending\");");
				sb.AppendLine("			#endregion");
				sb.AppendLine();
				sb.AppendLine("			PagedQueryResults<" + _currentView.PascalName + "DTO> retVal = new PagedQueryResults<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			" + _currentView.PascalName + "Collection." + _currentView.PascalName + "Paging paging = new " + _currentView.PascalName + "Collection." + _currentView.PascalName + "Paging();");
				sb.AppendLine("			paging.RecordsperPage = rpp;");
				sb.AppendLine("			paging.PageIndex = po;");
				sb.AppendLine("			paging.OrderByList.Add(new " + _currentView.PascalName + "Collection." + _currentView.PascalName + "PagingFieldItem(sortField, ascending));");
				sb.AppendLine();
				sb.AppendLine("			" + _currentView.PascalName + "Collection dalList = null;");
				sb.AppendLine("			if (string.IsNullOrEmpty(linq))");
				sb.AppendLine("			{");
				sb.AppendLine("				dalList = " + _currentView.PascalName + "Collection.RunSelect(x => true, paging);");
				sb.AppendLine("			}");
				sb.AppendLine("			else");
				sb.AppendLine("			{");
				sb.AppendLine("				System.Reflection.MethodInfo method = LINQDynamicCompile.GetLINQMethodPaged(linq, \"" + _model.CompanyName + "." + _model.ProjectName + ".Business\", \"" + _currentView.PascalName + "\");");
				sb.AppendLine("				dalList = (" + _currentView.PascalName + "Collection)method.Invoke(null, new object[] { paging });");
				sb.AppendLine("			}");
				sb.AppendLine();
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			foreach (" + _currentView.PascalName + " item in dalList)");
				sb.AppendLine("			{");
				sb.AppendLine("				" + _currentView.PascalName + "DTO newItem = new " + _currentView.PascalName + "DTO();");
				sb.AppendLine("				newItem.Fill(item);");
				sb.AppendLine("				list.Add(newItem);");
				sb.AppendLine("			}");
				sb.AppendLine();
				sb.AppendLine("			retVal.CurrentPage = paging.PageIndex;");
				sb.AppendLine("			double totalPages = Math.Ceiling((double)paging.RecordCount / (double)paging.RecordsperPage);");
				sb.AppendLine("			retVal.TotalPages = (int)totalPages;");
				sb.AppendLine("			retVal.TotalRecords = paging.RecordCount;");
				sb.AppendLine("			retVal.GridData = list;");
				sb.AppendLine();
				sb.AppendLine("			return retVal;");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		#endregion");
				sb.AppendLine();

				#endregion

				#region RunSelect Paged

				sb.AppendLine("		#region RunSelect Paged");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a result set.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public static void RunSelect(this List<" + _currentView.PascalName + "DTO> list, string linq)");
				sb.AppendLine("		{");
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine();
				sb.AppendLine("			" + _currentView.PascalName + "Collection dalList = null;");
				sb.AppendLine("			if (string.IsNullOrEmpty(linq))");
				sb.AppendLine("			{");
				sb.AppendLine("				dalList = " + _currentView.PascalName + "Collection.RunSelect(x => true);");
				sb.AppendLine("			}");
				sb.AppendLine("			else");
				sb.AppendLine("			{");
				sb.AppendLine("				System.Reflection.MethodInfo method = LINQDynamicCompile.GetLINQMethodAll(linq, \"" + _model.CompanyName + "." + _model.ProjectName + ".Business\", \"" + _currentView.PascalName + "\");");
				sb.AppendLine("				dalList = (" + _currentView.PascalName + "Collection)method.Invoke(null, new object[] { });");
				sb.AppendLine("			}");
				sb.AppendLine();
				sb.AppendLine("			if (list == null) list = new List<" + _currentView.PascalName + "DTO>();");
				sb.AppendLine("			foreach (" + _currentView.PascalName + " item in dalList)");
				sb.AppendLine("			{");
				sb.AppendLine("				" + _currentView.PascalName + "DTO newItem = new " + _currentView.PascalName + "DTO();");
				sb.AppendLine("				newItem.Fill(item);");
				sb.AppendLine("				list.Add(newItem);");
				sb.AppendLine("			}");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		#endregion");
				sb.AppendLine();

				#endregion

				sb.AppendLine("	}");
				sb.AppendLine();

			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

	}
}